﻿using Nature.Core.Exceptions;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;

namespace Nature.Core.Config
{
    /// <summary>
    ///     框架中所有的配置都应该放在XYConfig节点下面，由这里进行保证
    ///     自己的配置，只需要实现ConfigurationElement即可在此使用
    ///     其自身的节点为类名
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ConfigManager
    {
        private static Configuration cfg;

        private static readonly Dictionary<string, object> configContainer = new Dictionary<string, object>();

        private static string ConfigPath
        {
            get { return "Nature.config"; }
        }

        public static ConnectionStringsSection ConnectionStrings
        {
            get
            {
                return cfg.ConnectionStrings;
            }
        }

        public static T GetSection<T>(string name) where T : BaseConfigSection
        {
            T t = null;
            //如果配置容器中不存在该键，则从配置文件读取
            if (!configContainer.ContainsKey(name))
            {
                // Map the new configuration file.
                var configFileMap = new ExeConfigurationFileMap();
                configFileMap.ExeConfigFilename = AppDomain.CurrentDomain.BaseDirectory + ConfigPath;

                cfg = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
                t = cfg.GetSection(name) as T;
                //如果节点不存在
                if (t == null)
                    throw new FrameExcetpion("FCfg1", new[] { name });
                //将节点放入缓存
                configContainer[name] = t;
            }
            //如果存在，则直接从缓存读取
            else
            {
                t = configContainer[name] as T;
            }
            return t;
        }

        public static void SaveSection(string sectionName)
        {
            //如果配置信息不存在，则打开当前配置
            if (cfg == null)
            {
                cfg = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            }
            //保存配置
            cfg.Save();
            //刷新执行节点
            ConfigurationManager.RefreshSection(sectionName);
            //清空指定节点
            configContainer[sectionName] = null;
            //移除指定节点
            configContainer.Remove(sectionName);
        }
    }
}
